package upm.pb4agent.team5.custom;

import java.util.Collections;

import jade.content.lang.Codec.CodecException;
import jade.content.onto.OntologyException;
import jade.core.AID;
import jade.domain.FIPAException;
import jade.lang.acl.ACLMessage;
import jade.util.leap.ArrayList;
import jade.util.leap.Iterator;
import jade.util.leap.List;
import upm.pb4agent.ontology.Dock;
import upm.pb4agent.ontology.DockDesignation;
import upm.pb4agent.ontology.RegistrationForm;
import upm.pb4agent.ontology.TeamID;
import upm.pb4agent.team5.BaseAgent;
import upm.pb4agent.team5.util.RowerWrapper;

public class Manager extends BaseAgent {
	private static final long serialVersionUID = 7928863986513807507L;
	private final static String[] DOCKS = { "Dock1", "Dock2", "Dock3", "Dock4" }; // Docks names
	public final static String TEAM_ID = "5";
	public final static String DF_NAME = "Manager" + TEAM_ID;

	private List rowers = null;
	
	public Manager() {
		super(DF_NAME);
	}
		
	/**
     * Method executed when agent is initialized
     */	
	protected void setup()
	{
		System.out.println(getLocalName() + ": Enters the system");
		
		try {
			registerAgent(); // Registering in DF
			System.out.println(getLocalName() + ": Registered in DF");
			
			// Starting rowers and filling registration form
			rowers = (List) getArguments()[0]; // Getting rowers from list of arguments
			RegistrationForm registrationForm = getRegistrationForm(rowers);
			
			// Requesting inscription. Retries every 5 seconds if doesn't find RequestInscription
	     	addBehaviour(new BManagerRequestInscription(this, registrationForm));
		} catch (FIPAException e) {
			System.err.println(getLocalName()+": Cannot register in DF");
			doDelete(); // Terminating agent
		} 
	}
	
	public static java.util.List<RowerWrapper> getRowersOrderedByStaringKi(List rowers) {
		Iterator iterator = rowers.iterator();
		java.util.List<RowerWrapper> rowersWrapper = new java.util.ArrayList<RowerWrapper>();
		while (iterator.hasNext()) {
			AID rowerAID = (AID) iterator.next();
			rowersWrapper.add(new RowerWrapper(rowerAID, Rower.getStartingKi(rowerAID.getLocalName())));
		}
		Collections.sort(rowersWrapper);
		
		return rowersWrapper;
	}

	/**
	 * Fills registration form
	 * @return RegistrationForm
	 */
	public RegistrationForm getRegistrationForm(List rowers) {
		RegistrationForm registrationForm = new RegistrationForm();
		
		// Team definition
		TeamID teamId = new TeamID();
		teamId.setValue(TEAM_ID);
		
		// Ordering rowers per ki
		java.util.List<RowerWrapper> rowersWrapper = getRowersOrderedByStaringKi(rowers);
		
		// Dock definition
		List dds = new ArrayList();
		for (int i=0; i<4; i++) {
			if (i == 0)
				try {
					activateRower(rowersWrapper.get(i).getRowerAID());
				} catch (Exception e) {
					System.err.println(getLocalName() + ": Error activating rower!!!");
				}
			
			dds.add(getDockDesignation(DOCKS[i], rowersWrapper.get(i).getRowerAID()));			
		}

		registrationForm.setTeamID(teamId);
		registrationForm.setDockDesignation(dds);
		
		return registrationForm;
	}
	
	/**
	 * Fills a dock designation
	 * @param dockName String
	 * @param aid AID
	 * @return DockDesignation
	 */
	private DockDesignation getDockDesignation(String dockName, AID aid) {
		DockDesignation dockDesignation = new DockDesignation();
		dockDesignation.setRowerID(aid);
		Dock dock = new Dock();
		dock.setName(dockName);
		dockDesignation.setDock(dock);
		
		return dockDesignation;
	}	
	
	private void activateRower(AID rowerAID) throws CodecException, OntologyException {
		send(rowerAID, ACLMessage.INFORM, Rower.ACTIVATE_PROTOCOL);
	}
}

